S100 Computers

HomeS-100 Boards HistoryNew BoardsSoftwareBoards For Sale
ForumOther Web SitesQuizIndex  
  
Under Construction
A Collection of Useful Assembly Language Routines
Here is a growing collection of small but useful Z80, 8080 and 8086 Assembly Language routines I use time and time again in programs.  Other donations will be gratefully received.

  ; BDOS EQUATES for running these routines under CPM
;
RDCON       EQU   1     ;CP/M Read character
WRCON       EQU   2     ;CP/M Write character
PRINT       EQU   9     ;CP/M Print string
BDOS        EQU   5
ESC         EQU   1BH
CR          EQU   0DH
LF          EQU   0AH
 
; Main consol output routine using CPM.
; Character to be sent in [C].
; All registers unchanged
 
ZCO:  PUSH  AF
      PUSH  BC
      PUSH  DE
      LD    E,C
      LD    C,WRCON
      CALL  BDOS
      POP   DE
      POP   BC
      POP   AF
      RET
To Download Text Click Here

 
; Main consol input routine using CPM.
; Character returned in [A].
; All registers (except [A]) unchanged
 
ZCI:  PUSH  BC
      PUSH  DE
      LD    C,RDCON
      CALL  BDOS
      POP   DE
      POP   BC
      RET
To Download Text Click Here

 
; DISPLAY BIT PATTERN IN [A]  (ZILOG)
; All registers unchanged
; The output will look like:- (10100110)
 
ZBITS:PUSH  AF
      PUSH  BC
      PUSH  DE
      PUSH  AF
      LD    C,' '
      CALL  ZCO
      LD    C,'('
      CALL  ZCO
      POP   AF
      LD    E,A        
      LD    B,8
BQ2:  SLA   E    
      LD    A,18H
      ADC   A,A
      LD    C,A
      CALL  ZCO
      DJNZ  BQ2
      LD    C,')'
      CALL  ZCO
      POP   DE
      POP   BC
      POP   AF
      RET
To Download Text Click  Here

; Return with 2 HEX digits in [A] from keyboard
; If abort, Carry flag set & ESC is returned in [A]
; All registers unchanged except [A]    (INTEL)
 
GETHEX:
      PUSH  B
      MVI   C,RDCON
      CALL  BDOS        ;Get a character from keyboard & ECHO          
      CPI   ESC
      JZ    HEXABORT
      CPI   '/'         ;check 0-9, A-F
      JC    HEXABORT
      CPI   '9'+1
      JNC   HEXABORT
      CALL  ASBIN       ;Convert to binary
      RLC               ;Shift to high nibble
      RLC
      RLC
      RLC
      MOV   B,A         ;Store it
      PUSH  B
      MOV   C,RDCON
      CALL  BDOS        ;Get 2nd character from keyboard & ECHO
      POP   B          
      CPI   ESC
      JZ    HEXABORT
      CPI   '/'         ;check 0-9, A-F
      JC    HEXABORT
      CPI   '9'+1
      JNC   HEXABORT
      CALL  ASBIN       ;Convert to binary
      ORA   B           ;add in the first digit
      ORA   A           ;To return NC
      POP   B
      RET
;
HEXABORT:
      STC               ;Set Carry flag
      MVI   A,ESC
      POP   B
      RET
;                       ;Convert LC to UC
UPPER:CPI   'a'         ;must be >= lowercase a
      RC                ; else go back...
      CPI   'z'+1       ;must be <= lowercase z
      RNC               ; else go back...
      SUI   'a'-'A'           ;subtract lowercase bias
      RET
;                      
ASBIN:SUI   30H          ;ASCII TO BINARY CONVERSION ROUTINE
      CPI   0AH
      RM
      SUI   07H
      RET
 
 
To Download Text Click  Here

 
; DISPLAY CURRNT VALUE IN [A] (ZILOG)
; All registers unchanged
 
LBYTE:PUSH  AF
      PUSH  BC
      PUSH  AF
      RRCA
      RRCA
      RRCA
      RRCA
      CALL  CONV
      CALL  ZCO 
      POP   AF
SF598:CALL  CONV
      CALL  ZCO   ;Send to consol
      POP   BC
      POP   AF
      RET
;
CONV: AND   0FH   ;CONVERT HEX TO ASCII
      ADD   A,90H
      DAA
      ADC   A,40H
      DAA
      LD    C,A
      RET
To Download Text Click  Here

 
; DISPLAY CURRNT VALUE IN [A] (INTEL)
; All registers unchanged
 
LBYTE:PUSH  PSW  
      PUSH  B
      PUSH  PSW
      RRC
      RRC
      RRC
      RRC
      CALL  ZCONV
      POP   PSW
      CALL  ZCONV
      MVI   C,' '
      CALL  ZCO
      POP   B
      POP   PSW
      RET
;
ZCONV:ANI   0FH   ;HEX to ASCII and print it
      ADI   90H
      DAA
      ACI   40H
      DAA
      MOV   C,A
      CALL  ZCO
      RET
To Download Text Click  Here

 
; Return with 2 HEX digits in [A] from keyboard
; If abort, Carry flag set & ESC is returned in [A]
; All registers unchanged except [A]    (ZILOG)
 
GETHEX:
      PUSH  BC
      LD    C,RDCON                
      CALL  BDOS        ;Get a character from keyboard & ECHO
      CALL  UPPER
      CP    A,ESC
      JR    Z,HEXABORT
      CP    '/'         ;check 0-9, A-F
      JR    C,HEXABORT
      CP    'F'+1
      JR    NC,HEXABORT
      CALL  ASBIN       ;Convert to binary
      SLA   A
      SLA   A
      SLA   A
      SLA   A           ;Shift to high nibble  
      LD    B,A         ;Store it
      PUSH  BC          ;Because CP/M destroys BC
      LD    C,RDCON                
      CALL  BDOS        ;Get a character from keyboard & ECHO
      POP   BC
      CALL  UPPER
      CP    A,ESC
      JR    Z,HEXABORT
      CP    '/'         ;check 0-9, A-F
      JR    C,HEXABORT
      CP    'F'+1
      JR    NC,HEXABORT
      CALL  ASBIN       ;Convert to binary
      OR    A,B         ;add in the first digit
      OR    A,A         ;To return NC
      POP   BC
      RET
;
HEXABORT:
      SCF               ;Set Carry flag
      LD    A,ESC
      POP   BC
      RET
;
ASBIN:SUB   30H   ; ASCII TO BINARY CONVERSION ROUTINE
      CP    0AH
      RET   M
      SUB   07H
      RET
;
UPPER:CP    A,'a'
      RET   C
      CP    A,'z'+1
      RET   NC
      SUB   A,'a'-'A'
      RET
To Download Text Click  Here

; Binary to ASCII Decimal String Conversion Print Routine
; [DE] contains binary number to be displayed as a decimal number.
; Note String is built right->left in buffer
; Then printed out via CPM.         (ZILOG)
;
PRINT_DEC:
      LD    HL,BUFFER   ;Location to hold string
      LD    (BUFPTR),HL ;Save buffer pointer
      EX    DE,HL
      LD    A,0
      LD    (CURLEN),A  ;Current length of buffer is 0
      LD    A,H
      LD    (NGFLAG),A  ;Save Sign Value
      OR    A           ;Set FLAGS Value
      JP    P,CNVERT    ;JMP IF VALYE IS +
      EX    DE,HL
      LD    HL,0
      OR    A           ;CLEAR Carry
      SBC   HL,DE
                        ;Convert Value to a String
CNVERT:    
      LD    E,0         ;HL := HL DIV 10,  DE := HL MOD 10                               
      LD    B,16
      OR    A
DVLOOP:    
      RL    L           ;Do a 24-bit shift left
      RL    H
      RL    E
      LD    A,E
      SUB   10          ;If remainder is 10 or more next 1
      CCF
      JR    NC,DECCNT
      LD    E,A
DECCNT:    
      DJNZ  DVLOOP       ;continue until all bits are done
      RL    L
      RL    H
CHINS:LD    A,E         ;Insert next character into buffer
      ADD   A,'0'
      CALL  INSERT
      LD    A,H
      OR    L
      JR    NZ,CNVERT
     
EXIT: LD    A,(NGFLAG)  ;All done
      OR             ;Check it + or - overall
      JP    P,POS
      LD    A,'-'
      CALL  INSERT
POS:  LD    HL,BUFFER
      LD    A,(HL)      ;number of characters in buffer
      INC   A
      LD    C,A
      LD    B,0
      ADD   HL,BC       ;Point to end of buffer
      LD    (HL),'$'    ;Put in terminating character for CPM
      LD    DE,BUFFER+1 ;Now print the complete string
      LD    C,PRINT     ;(+1, because buffer count is in first posttion)
      CALL  BDOS
      RET
 
INSERT:     PUSH  HL     ;Save for now
      PUSH  AF
      LD    HL,(BUFPTR) ;Current end of buffer
      LD    D,H
      LD    E,L
      INC   DE          ;DE = End+1
      LD    (BUFPTR),DE
      LD    A,(CURLEN)
      OR    A
      JR    Z,EXITMR
      LD    C,A
      LD    B,0
      LDDR              ;Move entire buffer up one byte
EXITMR:    
      LD    A,(CURLEN)
      INC   A
      LD    (CURLEN),A
      LD    (HL),A
      EX    DE,HL
      POP   AF
      LD    (HL),A
      POP   HL
      RET
 
BUFPTR:     DS    2           ;pointer to last character in buffer
CURLEN:     DS    1           ;Current length
NGFLAG:     DS    1
BUFFER:     DB    '           $'    ;<<<<< Decimal string will be built here
To Download Text Click  Here

 
; Do a hexdump of the data in that is in a 512 byte (typically a BIOS DMA) buffer
; [HL] points to the buffer. Change values for [DE] below for different size buffers
; No registers modified    (INTEL)
 
 
HEXDUMP:
      PUSH  PSW         ;Save everything
      PUSH  D
      PUSH  H
      CALL  CRLF        ;CR/LF first
 
      MVI   D,32        ;print 32 lines
      MVI   E,16        ;16 characters across
      PUSH  D
      PUSH  H           ;Save the buffer location
;
SF172:CALL  ZCRLF
SF175:CALL  BLANK
      MOV   A,M
      CALL  LBYTE       ;Display A on CRT/LCD
      INX   H
      DCR   E
      JNZ   SF175
      MVI   E,16
      DCR   D
      JNZ   SF172
;
      CALL  ZCRLF
      POP   H           ;Get buffer address again
      POP   D           ;Get chars/line again
;
XF172:CALL  ZCRLF       ;Now show as ascii
XF175:CALL  BLANK       ;send a space character
      MOV   A,M
      ANI   7FH
      CPI   ' '         ;FILTER OUT CONTROL CHARACTERS
      JNC   XT33
XT22: MVI   A,'.'
XT33: CPI   07CH
      JNC   XT22
      MOV   C,A         ;SET UP TO SEND
      CALL  ZCO
      INX   H
      DCR   E
      JNZ   XF175
      MVI   E,16
      DCR   D
      JNZ   XF172
      CALL  ZCRLF
       POP   H
       POP   D
       POP   B
      POP   PSW
      RET
;
BLANK:MVI   C,' '
      CALL  ZCO
      RET
;
ZCRLF:MVI   C,CR
      CALL  ZCO
      MVI   C,LF
      CALL  ZCO
      RET
To Download Text Click Here